package com.zbw.printlibrary.printSub;

import static android.content.Context.MODE_PRIVATE;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.hardware.usb.UsbDevice;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import androidx.annotation.NonNull;

import com.zbw.printlibrary.bean.AttributeBean;
import com.zbw.printlibrary.printConnector.IPrintCallBack;
import com.zbw.printlibrary.printConnector.PrinterControlCommon;
import com.zbw.printlibrary.util.BitmapUtil;
import com.zbw.printlibrary.util.PrintContentToBitmap;
import com.zbw.printlibrary.util.PrintTextUtil;
import com.zbw.printlibrary.util.PrintThreadPoolManager;
import com.zbw.printlibrary.util.UsbController;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by cyj on 2019-07-26.
 * Usb打印
 */

public class PrintUsb extends PrinterControlCommon {
    private Context mContext;
    private final IPrintCallBack mCallBack;
    //usb打印
    public static UsbController usbCtrl;
    public static UsbDevice dev;
    private int USB_PID;
    private int USB_VID;

    public PrintUsb(Context context, IPrintCallBack callback) {
        mContext = context;
        this.mCallBack = callback;
    }

    public PrintUsb(Context context, IPrintCallBack callback,int vid,int pid) {
        USB_VID = vid;
        USB_PID = pid;
        mContext = context;
        this.mCallBack = callback;
    }

    @Override
    public void connectPrinter() {
        usbCtrl = new UsbController(mContext, mHandler);
        if(USB_VID == 0 && USB_PID == 0) {
            getUSBPram();
        }
        initPrint();
    }

    @Override
    public void disConnectPrinter() {
        try {
            if (usbCtrl != null) {
                usbCtrl.close();
                usbCtrl = null;
            }
            if (mContext != null) {
                mContext = null;
            }
            mCallBack.onDisConnect("断开成功", true);
        } catch (Exception e) {
            e.printStackTrace();
            mCallBack.onDisConnect("断开失败", false);
        }
    }

    /**
     * 每次打印
     * usb重新连接
     * usb连接很快，不像蓝牙。可以这么操作。
     * 能解决一部分客户打印机连接不稳定的情况
     */
    private void reconnect() {
        //每次打印之前，重新连接一下。（有客户打印机连接很不稳定，导致经常性的打印失败！）
        if (USB_VID != 0 || USB_PID != 0) {
            usbCtrl = new UsbController(mContext, mHandler);
            dev = usbCtrl.getDev(USB_VID, USB_PID);
            if (dev != null) {
                if (!(usbCtrl.isHasPermission(dev))) {
                    usbCtrl.getPermission(dev);
                    try {
                        Thread.sleep(300);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    @Override
    public void printTest(final List<String> StrList) {
        PrintThreadPoolManager.getInstance().executeTask(new Runnable() {
            @Override
            public void run() {
                try {
                    reconnect();
                    StringBuilder msg = new StringBuilder();
                    byte[] cmd = new byte[3];
                    cmd[0] = 0x1b;
                    cmd[1] = 0x21;
                    cmd[2] |= 0x10;
                    usbCtrl.sendByte(cmd, dev); // 倍宽、倍高模式
                    usbCtrl.sendMsg(PrintTextUtil.headCenter(StrList.get(0), 32), "GBK", dev);
                    cmd[2] &= 0xEF;
                    usbCtrl.sendByte(cmd, dev); // 取消倍高、倍宽模式
                    for (int i = 1; i < StrList.size() - 1; i++) {
                        msg.append(StrList.get(i)).append("\n");
                    }
                    msg.append(StrList.get(StrList.size() - 1));
                    usbCtrl.sendMsg(msg.toString(), "GBK", dev);
                    //切纸
                    usbCtrl.cutPaper(dev, 0);
                    mCallBack.onPrintResult(true);
                } catch (Exception e) {
                    e.printStackTrace();
                    mCallBack.onPrintResult(false);
                }
            }
        });
    }

    @Override
    public void printString(final List<AttributeBean> testList) {
        PrintThreadPoolManager.getInstance().executeTask(new Runnable() {
            @Override
            public void run() {
                try {
                    reconnect();
                    String msg;
                    for (int i = 0; i < testList.size(); i++) {
                        msg = testList.get(i).getContext();
                        usbCtrl.sendByte(BitmapUtil.setTextSize(testList.get(i).getFont_size()), dev);//1 两倍大小
                        switch (testList.get(i).getFont_gray()) {
                            case 0:
                                usbCtrl.sendByte(BitmapUtil.alignLeft(), dev);//居左
                                break;
                            case 1:
                                usbCtrl.sendByte(BitmapUtil.alignCenter(), dev);//居中
                                break;
                            case 2:
                                usbCtrl.sendByte(BitmapUtil.alignRight(), dev);//居右
                                break;
                        }
                        if (1 == testList.get(i).getContext_type()) {
                            Bitmap bitmap = testList.get(i).getBitmap();
                            usbCtrl.sendByte(BitmapUtil.genBitmapCode(bitmap), dev);
                        } else {
                            usbCtrl.sendMsg(msg, "GBK", dev);
                        }
                    }

                    //切纸
                    usbCtrl.cutJiaBoPaper(dev, 0);
                    mCallBack.onPrintResult(true);
                    //closeBitmap(testList);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    mCallBack.onPrintResult(false);
                }
            }
        });
    }

    /**
     * 主动释放图片资源
     * @param testList
     */
    private void closeBitmap(List<AttributeBean> testList){
        for (int i = 0; i < testList.size(); i++) {
            if(testList.get(i).getBitmap() != null){
                try{
                    testList.get(i).getBitmap().recycle();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void printStringAndBitmap(final List<String> testList, final LinkedHashMap<Integer, Bitmap> bitmapHashMap) {
        PrintThreadPoolManager.getInstance().executeTask(new Runnable() {
            @Override
            public void run() {
                try {
                    reconnect();
                    String msg;
                    for (int i = 0; i < testList.size(); i++) {
                        msg = testList.get(i);
                        if (i == 0) {
                            usbCtrl.sendByte(BitmapUtil.setTextSize(1), dev);//三倍大小
                            usbCtrl.sendByte(BitmapUtil.alignCenter(), dev);//居中
                        } else if (i == 1) {
                            usbCtrl.sendByte(BitmapUtil.setTextSize(1), dev);//两倍大小
                            usbCtrl.sendByte(BitmapUtil.alignCenter(), dev);//居中
                        } else {
                            //左对齐
                            if (msg.startsWith("牌号")) {
                                usbCtrl.sendByte(BitmapUtil.setTextSize(1), dev);//两倍大小
                            } else {
                                usbCtrl.sendByte(BitmapUtil.setTextSize(0), dev); //取消倍宽、倍高模式
                            }
                            usbCtrl.sendByte(BitmapUtil.alignLeft(), dev);//左对齐
                        }
                        usbCtrl.sendMsg(msg, "GBK", dev);
                        Bitmap bitmap = bitmapHashMap.get(i);
                        if (bitmap != null) {
                            usbCtrl.sendByte(BitmapUtil.alignCenter(), dev);//居中
                            usbCtrl.sendByte(BitmapUtil.genBitmapCode(bitmap), dev);
                        }
                    }
                    if (bitmapHashMap.size() > 0) {
                        usbCtrl.sendByte(BitmapUtil.alignCenter(), dev);//居中
                        //传入的position位置大于list的话默认在最后面打印
                        for (Map.Entry<Integer, Bitmap> entry : bitmapHashMap.entrySet()) {
                            if (entry.getKey() > testList.size() - 1) {
                                Bitmap showBitmap = entry.getValue();
                                usbCtrl.sendByte(BitmapUtil.genBitmapCode(showBitmap), dev);
                            }
                        }
                    }
                    //切纸
                    usbCtrl.cutPaper(dev, 0);
                    mCallBack.onPrintResult(true);
                } catch (Exception e) {
                    e.printStackTrace();
                    mCallBack.onPrintResult(false);
                }
            }
        });
    }

    @Override
    public void blueConnect(String address) {

    }

    @Override
    public void disBlueConnect() {

    }

    public void getUSBPram() {
        SharedPreferences share = mContext.getSharedPreferences("SHEZHI", MODE_PRIVATE);
        USB_PID = share.getInt("USB_PID", 0);
        USB_VID = share.getInt("USB_VID", 0);
    }

    @SuppressLint("HandlerLeak")
    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            Log.i("回调",msg.toString());


        }
    };

    public void initPrint() {
        int vid = USB_VID;
        int pid = USB_PID;
        dev = usbCtrl.getDev(vid, pid);
        if (dev != null) {
            mCallBack.onConnect("连接成功",true);
            if (!(usbCtrl.isHasPermission(dev))) {
                usbCtrl.getPermission(dev);
            }
        }
    }

    @Override
    public void openMoneyBox() {
        if (usbCtrl != null) {
            usbCtrl.openCashBox(dev);
            usbCtrl.openJaboCashBox(dev);
        }
    }


    @Override
    public boolean isConnected() {
        return usbCtrl == null;
    }

    @Override
    public void printString(List<AttributeBean> testList, int width) {
        List<List<AttributeBean>> allData = new ArrayList<>();
        List<AttributeBean> temList = null;
        for (int i = 0; i < testList.size(); i++) {
            if(temList == null){
                temList = new ArrayList<>();
            }
            temList.add(testList.get(i));
            if(testList.get(i).isFont_line()){
                allData.add(temList);
                temList = null;
            }
        }
        List<AttributeBean> data = new ArrayList<>();
        for (int i = 0; i < allData.size(); i++) {
            PrintContentToBitmap bt = new PrintContentToBitmap(allData.get(i),width);
            try {
                Bitmap bitmap = bt.Print();
                data.add(new AttributeBean(0,0,"",1,bitmap));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        printString(data);
    }

}
